/**
 * Klasa opisujaca realizacje predykatu
 */

package stripsLanguage;

import java.util.ArrayList;
import java.util.List;

import exceptions.PredicateException;

import stripsLanguage.Instance;

public class Predicate extends PredicateType {
	
	/** identifier of the predicate **/
	private int IdOfPredicate;
	
	/** informs whether it is a negation of predicate **/
	private boolean Negation = true; 
	
	/** list of arguments of the predicate **/
	protected List<Instance> Arguments = null;

	/** creates a predicate with specified nr of args **/
	public Predicate(
		int idOfPredicate,
		int nrOfType,
		String name,
		int nrOfArgs)
	{
		super(nrOfType, name, nrOfArgs);
		IdOfPredicate = idOfPredicate;
		Arguments = new ArrayList<Instance>();
	}
	
	public void addArgument(int idOfArg, String nameOfArg)
	{
		Arguments.add(new Instance(nameOfArg, idOfArg));
	}

	
	/**
	 * creates an exact copy of this predicate
	 * @return
	 */
	public Predicate copyPredicate()
	{
		Predicate p = new Predicate(
			IdOfPredicate,
			getNrOfType(),
			getName(),
			getNrOfArgs()
			);
		if(!Negation) p.setNegation();
		for(Instance i: Arguments)
			p.addArgument(i.getId(), i.getName());
		return p;
	}

	/**
	 * creates an exact copy of this predicate
	 * @return
	 */
	public Predicate copyPredicateForOperator()
	{	
		Predicate p = new Predicate(
			IdOfPredicate,
			getNrOfType(),
			getName(),
			getNrOfArgs()
			);
		if(!Negation) p.setNegation();
		for(Instance i: Arguments)
			p.addArgument(i.getId(), null);
		return p;
	}	
	
	public List<Instance> getArguments()
	{
		return Arguments;
	}
	
	public int getIdOfPredicate() {
		return IdOfPredicate;
	}

	public void setIdOfPredicate(int i) {
		IdOfPredicate = i;
	}

	/**
	 * returns id of instance in specified position
	 * @param position
	 * @return
	 */
	public int getInstance(int position)
	{
		return Arguments.get(position).getId();
	}
	
	public boolean getNegation()
	{
		return Negation;
	}
	
	/**
	 * sets id of instance on specified position
	 * @param position
	 * @param idOfInstance
	 */
	public void setInstance(
		int position,
		Instance instance)
	{
		Arguments.set(position, instance);
	}
	
	public void setNegation()
	{
		Negation = false;
	}
	
	public String toString(boolean withValue) throws PredicateException
	{
		String s = "(" + IdOfPredicate + ", " + getName();
		if(withValue == true)
			s += "," + this.Negation;
		for(Instance i: this.Arguments)
		{
			if(i == null)
				throw new PredicateException("Predicate.toString: cant print null Instance");
			s += ", [" +  i.getId() +"," + i.getName() +"]";
		}
		s += ") ";
		return s;
	}
	
	
}
